﻿using Ninject.Conditions;
using Ninject.Core;
using Ninject.Core.Behavior;
using Ninject.Core.Parameters;
using TestBat.IModels.Domain;
using TestBat.IViewModels.Base;
using TestBat.IViewModels.Dialogs;
using TestBat.IViewModels.Factories;
using TestBat.IViewModels.Windows;
using TestBat.IViewModels.Workspaces.Gradings;
using TestBat.IViewModels.Workspaces.Results;
using TestBat.IViewModels.Workspaces.Schedules;
using TestBat.IViewModels.Workspaces.Settings;
using TestBat.IViewModels.Workspaces.Tasks;
using TestBat.IViewModels.Workspaces.Trainees;
using TestBat.ViewModels.Base;
using TestBat.ViewModels.Dialogs;
using TestBat.ViewModels.Factories;
using TestBat.ViewModels.Windows;
using TestBat.ViewModels.Workspaces.Gradings;
using TestBat.ViewModels.Workspaces.Results;
using TestBat.ViewModels.Workspaces.Schedules;
using TestBat.ViewModels.Workspaces.Settings;
using TestBat.ViewModels.Workspaces.Tasks;
using TestBat.ViewModels.Workspaces.Trainees;

namespace TestBat.GuyWire.Configurators
{
    public class ViewModelModule : StandardModule
    {
        public override void Load()
        {
            // bind view-models
            Bind<ITaskTreeViewModel>().To<ReadOnlyTaskTreeViewModel>().Only(When.Context.Variable("readOnly").IsDefined);
            Bind<ITaskTreeViewModel>().To<TaskTreeViewModel>();
            Bind<ITasksViewModel>().To<TasksViewModel>();
            Bind<ISchedulesViewModel>().To<SchedulesViewModel>();
            Bind<ITraineesViewModel>().To<TraineesViewModel>();
            Bind<ISettingsViewModel>().To<SettingsViewModel>();
            Bind<IMainWindowViewModel>().To<MainWindowViewModel>();

            Bind<IRootTaskFolderViewModel>().To<RootTaskFolderViewModel>();
            Bind<ILeafTaskFolderViewModel>().To<LeafTaskFolderViewModel>();
            Bind<IChoiceListViewModel>().To<ChoiceListViewModel>();
            Bind<IChoiceViewModel>().To<ChoiceViewModel>();

            Bind<IScheduleViewModel>().To<ScheduleViewModel>();
            Bind<IScheduleListViewModel>().To<ScheduleListViewModel>();
            Bind<IScheduleTaskListViewModel>().To<ScheduleTaskListViewModel>();
            Bind<IScheduleTaskViewModel>().To<ScheduleTaskViewModel>();
            Bind<IScheduleTraineeGroupViewModel>().To<ScheduleTraineeGroupViewModel>();
            Bind<IScheduleTraineeGroupListViewModel>().To<ScheduleTraineeGroupListViewModel>();

            Bind<ITraineeGroupViewModel>().To<TraineeGroupViewModel>();
            Bind<ITraineeGroupListViewModel>().To<TraineeGroupListViewModel>();
            Bind<IAddTraineeGroupViewModel>().To<AddTraineeGroupViewModel>();
            Bind<ITraineeListViewModel>().To<TraineeListViewModel>();
            Bind<ITraineeViewModel>().To<TraineeViewModel>();
            Bind<IAddTraineeViewModel>().To<AddTraineeViewModel>();
            Bind<IAvailableTraineeGroupListViewModel>().To<AvailableTraineeGroupListViewModel>();
            Bind<IAssociatedTraineeGroupListViewModel>().To<AssociatedTraineeGroupListViewModel>();

            Bind<IGradingsViewModel>().To<GradingsViewModel>();
            Bind<IScheduleComboBoxViewModel>().To<ScheduleComboBoxViewModel>();
            Bind<IScheduleComboBoxItemViewModel>().To<ScheduleComboBoxItemViewModel>();
            Bind<ITraineeComboBoxItemViewModel>().To<TraineeComboBoxItemViewModel>();
            Bind<ITraineeComboBoxViewModel>().To<TraineeComboBoxViewModel>();
            Bind<IGradingViewModel>().To<GradingViewModel>();

            Bind<IResultsViewModel>().To<ResultsViewModel>();
            Bind<IResultScheduleListViewModel>().To<ResultScheduleListViewModel>();
            Bind<IResultScheduleViewModel>().To<ResultScheduleViewModel>();
            Bind<IResultTraineeListViewModel>().To<ResultTraineeListViewModel>();
            Bind<IResultTraineeViewModel>().To<ResultTraineeViewModel>();
            Bind<IResultTestTaskListViewModel>().To<ResultTestTaskListViewModel>();
            Bind<IResultTestTaskViewModel>().To<ResultTestEssayTaskViewModel>().Only(When.Context.Parameter<ConstructorArgumentParameter>("testTask").Type.Matches(
                p =>
                {
                    return typeof(ITestEssayTask).IsAssignableFrom(p);
                }));
            Bind<IResultTestTaskViewModel>().To<ResultTestMultipleChoiceTaskViewModel>().Only(When.Context.Parameter<ConstructorArgumentParameter>("testTask").Type.Matches(
                p =>
                {
                    return typeof(ITestMultipleChoiceTask).IsAssignableFrom(p);
                }));
            Bind<IResultTestTaskViewModel>().To<ResultTestMultipleResponseTaskViewModel>().Only(When.Context.Parameter<ConstructorArgumentParameter>("testTask").Type.Matches(
                p =>
                {
                    return typeof(ITestMultipleResponseTask).IsAssignableFrom(p);
                }));

            Bind<ITaskViewModel>().To<EssayTaskViewModel>().Only(When.Context.Parameter<ConstructorArgumentParameter>("task").Type.Matches(
                p =>
                {
                    return typeof(IEssayTask).IsAssignableFrom(p);
                }));
            Bind<ITaskViewModel>().To<MultipleChoiceTaskViewModel>().Only(When.Context.Parameter<ConstructorArgumentParameter>("task").Type.Matches(
                p =>
                {
                    return typeof(IMultipleChoiceTask).IsAssignableFrom(p);
                }));
            Bind<ITaskViewModel>().To<MultipleResponseTaskViewModel>().Only(When.Context.Parameter<ConstructorArgumentParameter>("task").Type.Matches(
                p =>
                {
                    return typeof(IMultipleResponseTask).IsAssignableFrom(p);
                }));

            Bind<IUnsavedChangesViewModel>().To<UnsavedChangesViewModel>().Using<SingletonBehavior>();

            // bind dialogs
            Bind<IDialogMediator>().To<DialogMediator>().Using<SingletonBehavior>();
            Bind<ISetupWizardWindowViewModel>().To<SetupWizardWindowViewModel>();

            // bind factories
            Bind<IScheduleTaskViewModelFactory>().To<ScheduleTaskViewModelFactory>().Using<SingletonBehavior>();
            Bind<IScheduleViewModelFactory>().To<ScheduleViewModelFactory>().Using<SingletonBehavior>();
            Bind<ISchedulesViewModelFactory>().To<SchedulesViewModelFactory>().Using<SingletonBehavior>();
            Bind<IScheduleTasksViewModelFactory>().To<ScheduleTasksViewModelFactory>().Using<SingletonBehavior>();

            Bind<ILeafTaskFolderViewModelFactory>().To<LeafTaskFolderViewModelFactory>().Using<SingletonBehavior>();
            Bind<IRootTaskFolderViewModelFactory>().To<RootTaskFolderViewModelFactory>().Using<SingletonBehavior>();
            Bind<ITaskTreeViewModelFactory>().To<TaskTreeViewModelFactory>().Using<SingletonBehavior>();
            Bind<ITaskViewModelFactory>().To<TaskViewModelFactory>().Using<SingletonBehavior>();
            Bind<ITasksViewModelFactory>().To<TasksViewModelFactory>().Using<SingletonBehavior>();

            Bind<ITraineesViewModelFactory>().To<TraineesViewModelFactory>().Using<SingletonBehavior>();
            Bind<ITraineeGroupViewModelFactory>().To<TraineeGroupViewModelFactory>().Using<SingletonBehavior>();
            //Bind<ITraineeTreeViewModelFactory>().To<TraineeTreeViewModelFactory>().Using<SingletonBehavior>();
        }
    }
}
